package com.hzhq.contract.service.impl;

import com.hzhq.contract.bean.dto.ContractStatusDTO;
import com.hzhq.contract.bean.entity.ContractStatus;
import com.hzhq.contract.convert.ContractStatusConvertBasic;
import com.hzhq.contract.repo.ContractStatusRepository;
import com.hzhq.contract.service.ContractStatusService;
import com.hzhq.contract.status.DefaultValue;
import com.hzhq.contract.util.ConvertUtil;
import com.hzhq.contract.util.Page2ResultUtil;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author: hzhq1255
 * @mail: hzhq1255@163.com
 * @date: 2021/4/18 23:57
 * @desc:
 */
@Service
public class ContractStatusServiceImpl implements ContractStatusService {

    @Autowired
    ContractStatusRepository statusRepo;

    @Autowired
    MongoTemplate mongoTemplate;

    @Override
    public List<ContractStatusDTO> getAllList() {
        return statusRepo.findAllByDeleted(DefaultValue.NOT_DELETED).stream().map(ContractStatusConvertBasic.INSTANCE::poToDto).collect(Collectors.toList());
    }

    @Override
    public Page<ContractStatusDTO> getAllPage(Integer currentPage, Integer pageSize) {
        Pageable pageable = Page2ResultUtil.buildPageableByParam(currentPage, pageSize, Sort.by(Sort.Direction.DESC, "statusId"));
        return statusRepo.findAllByDeleted(DefaultValue.NOT_DELETED,pageable).map(ContractStatusConvertBasic.INSTANCE::poToDto);
    }



    @Override
    public Page<ContractStatusDTO> searchByName(String name, Integer currentPage, Integer pageSize) {
        Pageable pageable = Page2ResultUtil.buildPageableByParam(currentPage, pageSize, Sort.by(Sort.Direction.DESC, "statusId"));
        return statusRepo.findByStatusNameLikeAndDeleted(name,DefaultValue.NOT_DELETED,pageable).map(ContractStatusConvertBasic.INSTANCE::poToDto);
    }

    @Override
    public ContractStatusDTO getOneById(String id) {
        return ContractStatusConvertBasic.INSTANCE.poToDto(statusRepo.findByStatusIdAndDeleted(new ObjectId(id),DefaultValue.NOT_DELETED).orElse(null));
    }

    @Override
    public ContractStatusDTO getOneByName(String name)  {
        return ContractStatusConvertBasic.INSTANCE.poToDto(statusRepo.findByStatusNameAndDeleted(name,DefaultValue.NOT_DELETED).orElse(null));
    }

    @Override
    public ContractStatusDTO getOneByContractIdAndStatusName(String contractId, String statusName) {
        Optional<ContractStatus> contractStatus = statusRepo.findByContractIdAndStatusNameAndDeleted(ConvertUtil.stringToObjectId(contractId),statusName,DefaultValue.NOT_DELETED);
        return contractStatus.map(ContractStatusConvertBasic.INSTANCE::poToDto).orElse(null);
    }

    @Override
    public ContractStatusDTO getOneByContractIdAndStatusId(String contractId, String statusId) {
        Optional<ContractStatus> contractStatus = statusRepo.findByContractIdAndStatusIdAndDeleted(
                ConvertUtil.stringToObjectId(contractId),
                ConvertUtil.stringToObjectId(statusId),
                DefaultValue.NOT_DELETED);
        return contractStatus.map(ContractStatusConvertBasic.INSTANCE::poToDto).orElse(null);
    }

    @Override
    public ContractStatusDTO save(ContractStatusDTO contractStatusDTO) {
        return ContractStatusConvertBasic.INSTANCE.poToDto(statusRepo.save(ContractStatusConvertBasic.INSTANCE.dtoToPo(contractStatusDTO)));
    }

    @Override
    public List<ContractStatusDTO> saveAll(List<ContractStatusDTO> contractStatusDTOList) {
        return statusRepo.saveAll(contractStatusDTOList.stream().map(ContractStatusConvertBasic.INSTANCE::dtoToPo).collect(Collectors.toList())).stream().map(ContractStatusConvertBasic.INSTANCE::poToDto).collect(Collectors.toList());
    }

    @Override
    public List<String> deleteByIds(List<ObjectId> ids) {
        List<ContractStatus> statusList = statusRepo.findByStatusIdInAndDeleted(ids,DefaultValue.NOT_DELETED)
                .stream().peek(e -> e.setDeleted(DefaultValue.DELETED)).collect(Collectors.toList());
        return statusRepo.saveAll(statusList).stream().map(e -> e.getStatusId().toString()).collect(Collectors.toList());
    }

    @Override
    public String deleteById(String id) {
        Optional<ContractStatus> statusOptional = statusRepo.findByStatusIdAndDeleted(ConvertUtil.stringToObjectId(id),DefaultValue.NOT_DELETED);
        if (statusOptional.isPresent()){
            ContractStatus status = statusOptional.get();
            status.setDeleted(DefaultValue.DELETED);
            return statusRepo.save(status).getStatusId().toString();
        }
        return null;
    }

    @Override
    public Page<ContractStatusDTO> searchAllPages(ContractStatusDTO statusDTO, Integer currentPage, Integer pageSize) {
        ContractStatus status = ContractStatusConvertBasic.INSTANCE.dtoToPo(statusDTO);
        status.setDeleted(DefaultValue.NOT_DELETED);
        Sort sort = Sort.by(Sort.Direction.DESC,"statusId");
        Pageable pageable = Page2ResultUtil.buildPageableByParam(currentPage, pageSize, sort);
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("statusName",ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("desc",ExampleMatcher.GenericPropertyMatchers.contains());
        Example<ContractStatus> statusExample = Example.of(status,exampleMatcher);

        return statusRepo.findAll(statusExample,pageable).map(ContractStatusConvertBasic.INSTANCE::poToDto);
    }

    @Override
    public Page<ContractStatusDTO> searchAllPageByQuery(Query query, Integer currentPage, Integer pageSize) {
        Pageable pageable = Page2ResultUtil.buildPageableByParam(currentPage,pageSize,Sort.by(Sort.Direction.DESC,"statusId"));
        long count = mongoTemplate.count(query,ContractStatus.class);
        List<ContractStatus> statusPage = mongoTemplate.find(query.with(pageable),ContractStatus.class);
        Page<ContractStatus> contractStatusPage = new PageImpl<>(statusPage, pageable, count);
        return contractStatusPage.map(ContractStatusConvertBasic.INSTANCE::poToDto);
    }



}
